---
title: Redaction Plugin
description: Securely and permanently remove text and image content from a PDF document.
searchable: true
---

import { Callout } from '@/components/callout'

# Redaction Plugin

The Redaction Plugin provides the tools to permanently remove sensitive content from a PDF document. Unlike annotations which are simply layered on top, redaction is a destructive process that alters the underlying PDF content, making it unrecoverable.

The process involves two main stages:
1.  **Marking**: Users mark content for redaction by selecting text or drawing a rectangle over an area. These marks are called "pending redactions."
2.  **Committing**: Users apply the pending redactions, which permanently removes the marked content from the document in the viewer's memory and, optionally, draws black boxes in its place.

<Callout type="warning" title="Destructive Action">
Redaction is an irreversible process. Once committed, the original content is removed and cannot be restored from the document.
</Callout>

## Installation

The plugin has optional but highly recommended dependencies on the `Selection` and `Interaction Manager` plugins, which are required for marking text and areas, respectively.

```sh npm2yarn
npm install @embedpdf/plugin-redaction @embedpdf/plugin-selection @embedpdf/plugin-interaction-manager
````

## Registration

Import `RedactionPluginPackage` and its dependencies, then add them to the `plugins` array. The dependencies should be registered first.

```tsx {6, 18-20}
import { createPluginRegistration } from '@embedpdf/core'
import { EmbedPDF } from '@embedpdf/core/react'
// ... other imports
import { InteractionManagerPluginPackage } from '@embedpdf/plugin-interaction-manager/react'
import { SelectionPluginPackage } from '@embedpdf/plugin-selection/react'
import { RedactionPluginPackage } from '@embedpdf/plugin-redaction/react'

const plugins = [
  // ... other essential plugins
  createPluginRegistration(LoaderPluginPackage, { /* ... */ }),
  createPluginRegistration(RenderPluginPackage),

  // Register dependencies first
  createPluginRegistration(InteractionManagerPluginPackage),
  createPluginRegistration(SelectionPluginPackage),

  // Register and configure the redaction plugin
  createPluginRegistration(RedactionPluginPackage, {
    drawBlackBoxes: true, // Draw black boxes over redacted content
  }),
]
```

## Usage

The plugin's functionality is primarily managed through the `<RedactionLayer />` component and the `useRedaction` hook.

### 1\. Add the `<RedactionLayer />`

This component is responsible for rendering all redaction-related UI, including the text selection highlights, area selection marquee, and all pending redaction marks. It must be placed inside your `Scroller`'s `renderPage` prop and be a child of the `<PagePointerProvider>`.

```tsx {2, 10}
import { PagePointerProvider } from '@embedpdf/plugin-interaction-manager/react';
import { RedactionLayer } from '@embedpdf/plugin-redaction/react';

// ...
<Scroller
  renderPage={({ width, height, pageIndex, scale, rotation }) => (
    <PagePointerProvider {...{ pageIndex, width, height, scale, rotation }}>
      <RenderLayer pageIndex={pageIndex} />
      <SelectionLayer pageIndex={pageIndex} />
      <RedactionLayer pageIndex={pageIndex} scale={scale} rotation={rotation} />
    </PagePointerProvider>
  )}
/>
```

### 2\. Build a Redaction Toolbar

The `useRedaction` hook provides the `state` of the redaction process (e.g., how many marks are pending) and a `provides` object with methods to control it. You can build a toolbar to allow users to switch between redaction modes and apply their changes.

```tsx
import { useRedaction, RedactionMode } from '@embedpdf/plugin-redaction/react';

const RedactionToolbar = () => {
  const { state, provides } = useRedaction();

  return (
    <div>
      <button onClick={() => provides?.toggleRedactSelection()}>Mark Text</button>
      <button onClick={() => provides?.toggleMarqueeRedact()}>Mark Area</button>
      <span>{state.pendingCount} pending marks</span>
      <button
        onClick={() => provides?.commitAllPending()}
        disabled={state.pendingCount === 0}
      >
        Apply All Redactions
      </button>
    </div>
  );
};
```

### 3\. Create a Menu for Pending Marks

You can provide a `selectionMenu` render prop to the `<RedactionLayer />` to display a custom UI when a user clicks on a pending redaction mark. This is useful for allowing users to apply or remove individual marks.

```tsx
import { SelectionMenuProps, useRedaction } from '@embedpdf/plugin-redaction/react';

// A custom menu component
const RedactionMenu = ({ item, selected, menuWrapperProps }: SelectionMenuProps) => {
  const { provides } = useRedaction();
  if (!selected) return null;

  return (
    <div {...menuWrapperProps}>
      <div
        style={{ 
          position: 'absolute', 
          top: rect.size.height + 10, 
          left: 0, 
          pointerEvents: 'auto' 
        }}
      >
        <button onClick={() => provides?.removePending(item.page, item.id)}>Remove</button>
      </div>
    </div>
  );
};

// Pass it to the layer
<RedactionLayer
  pageIndex={pageIndex}
  scale={scale}
  rotation={rotation}
  selectionMenu={(props) => <RedactionMenu {...props} />}
/>
```

## Live Example

This example demonstrates the full redaction workflow. Use the "Mark Text" and "Mark Area" buttons to queue redactions. Click a pending mark to see the option to remove it. Finally, click "Apply All" to permanently redact the content.

import { PDFViewer } from '../code-examples/redaction-example';

<PDFViewer />

## API Reference

### Configuration (`RedactionPluginConfig`)

| Option | Type | Description |
| :--- | :--- | :--- |
| **`drawBlackBoxes`** | `boolean` | If `true`, a black rectangle is drawn over the redacted content after committing. **Default**: `true` |

### Component: `<RedactionLayer />`

Renders all UI related to marking and managing redactions.

| Prop | Type | Description |
| :--- | :--- | :--- |
| **`pageIndex`** | `number` | **(Required)** The page index this layer corresponds to. |
| **`scale`** | `number` | **(Required)** The current zoom scale of the page. |
| **`rotation`** | `Rotation` | **(Required)** The current rotation of the page. |
| **`selectionMenu`** | `(props: SelectionMenuProps) => JSX.Element` | A render prop for a custom menu that appears when a pending redaction is selected. |

### Hook: `useRedaction()`

Connects your components to the redaction plugin's state and methods.

#### Returns

| Property | Type | Description |
| :--- | :--- | :--- |
| **`state`** | `RedactionState` | An object containing the current state of the redaction process. |
| **`provides`**| `RedactionCapability \| null` | An object with methods to control the plugin, or `null` if not ready. |

#### `RedactionState` Properties

| Property | Type | Description |
| :--- | :--- | :--- |
| **`isRedacting`**| `boolean`| `true` when any redaction mode is active. |
| **`activeType`** | `RedactionMode \| null` | The currently active mode (`'marqueeRedact'` or `'redactSelection'`). |
| **`pending`**| `object`| A map of pending redactions, keyed by page number. |
| **`pendingCount`**| `number`| The total number of pending redactions across all pages. |
| **`selected`**| `object \| null`| The currently selected pending redaction, if any. |

#### `RedactionCapability` Methods

A selection of key methods available on the `provides` object:

| Method | Description |
| :--- | :--- |
| **`toggleRedactSelection()`** | Toggles the text redaction mode. |
| **`toggleMarqueeRedact()`** | Toggles the area redaction mode. |
| **`addPending(items)`** | Programmatically adds new `RedactionItem`s to the pending queue. |
| **`removePending(page, id)`** | Removes a specific pending redaction mark. |
| **`clearPending()`** | Removes all pending redaction marks. |
| **`commitAllPending()`** | **(Destructive)** Applies all pending redactions to the document. Returns a `Task`. |
| **`commitPending(page, id)`** | **(Destructive)** Applies a single pending redaction. Returns a `Task`. |
| **`onStateChange(cb)`** | Subscribes to any change in the `RedactionState`. |
| **`onRedactionEvent(cb)`** | Subscribes to events like adding, removing, or committing redactions. |